#ifndef GAMEFUNC_H
#define GAMEFUNC_H

#include "queue.h"
#include "gameinit.h"
#include "c_detect.h"
#include "GQueue.h"
#include "config.h"
#include "ints.h"
#include "structs.h"
#include "vg.h"
#include "kbc.h"

#define INPUT_STATUS_1      0x03da
#define VRETRACE            0x08

#define MAP_RATIO_MAXX 30
#define MAP_RATIO_MINX 0
#define MAP_RATIO_MAXY 50
#define MAP_RATIO_MINY 0

#define MIN_XSPEED 10
#define MIN_YSPEED 10

#define MONSTER_XSPEED 5
#define MONSTER_YSPEED 10
#define RIGHT_DIRECTION 1
#define LEFT_DIRECTION -1


/**
 * Esta função esta função verifica se existe alguma tecla do teclado 
 * na queue ou se existe algum movimento do rato, 
 * e chama as funções que os processam.
 */
void 	GetInput();


/**
 * Esta função faz uma actualização a todas as estruturas do jogo numa iteração de um determinado nível.
 * A função também indica se o jogador perdeu esse nível, retornando 0 nessa situação.
 *
 * @param level apontador para Level a ser actualizado.
 * @return int indica se o utilizador perdeu o nível/jogo.
 */
int 	Update(Level *level);

/**
 * Esta função é responsável por desenhar um nível numa iteração, segundo os valores actuais desse nível.
 *
 * @param level Level a ser desenhado
 */
void 	Draw(Level level);

/**
 * Esta desenha o número de vidas do Hero no canto superior direito do ecrâ.
 */
void 	displayLives();

/**
 * Esta função move um inimigo numa iteração, movendo na direção do Hero. Esta função tem em atenção
 * que um inimigo tem um tempo de reacção. Esta função também actualiza a Sprite do inimigo para este
 * ficar desenhado na direcção do Hero. 
 *
 * @param enemy apontador para um Enemy que vai ser movido
 * @param hero Hero que vai ser usado para comparar a posição e mover na direcção correspondente.
 */
void moveEnemy(Enemy *enemy, Hero hero);

/**
 * Esta função move um monstro numa iteração, e é usada no nível 3, em que o monstro tem um
 * movimento pré-definido.
 * 
 * @param enemy apontador para um Enemy que vai ser movido
 */
void moveMonster(Enemy *enemy);

/**
 * Esta função movimenta uma pedra Stone numa iteração. A pedra vai ser movida segundo os seus
 * parâmetros, que são definidos na altura em que o utilizador pressiona o rato.
 *
 * @param stone apontador para Stone que é a pedra a ser movida.
 */
void moveStone(Stone* stone);

/**
 * Esta função recebe os dados de uma GQueue que tem as informações do rato,
 * e preenche as variáveis correspondentes. (MSBy1, MSBy2, MSby3, dx, dy, xov, yov, lmb, mmb, rmb)
 */
void parse_mouse_event();

/**
 * Esta função processa os dados do rato, actualizando a posição da mira.
 */
void process_mouse_event();

#endif
